package com.piper.gateway.config;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.piper.auth.properties.JwtProperties;
import com.piper.auth.utils.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

@Slf4j
@Component
public class AccessFilter extends ZuulFilter {

    @Resource
    private JwtProperties jwtProperties;

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Override
    public String filterType() {
        /**
         * pre 请求在被路由之前调用
         * routing 路由请求时被调用
         * error 处理请求时发生错误时调用
         * post 在routing和error之后调用
         */
        return PRE_TYPE;// 前置过滤器
    }

    @Override
    public int filterOrder() {
        return 0;// 优先级为0，数字越大，优先级越低
    }

    /**
     * 是否执行该过滤器
     * @return
     */
    @Override
    public boolean shouldFilter() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String servletPath = request.getServletPath();

        //是否是登录接口
        return !servletPath.equals("/auth/login");
    }

    @Override
    public Object run() {
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();

        log.info("send {} request to {}", request.getMethod(), request.getRequestURL());

        //获取context-path加servlet-path
        String requestURI = request.getRequestURI();

        //如果是zuul开头的url，则去掉zuul再去资源校验
        if (requestURI.startsWith("/zuul")) {
            requestURI = requestURI.substring(5);
        }

        //获取token
        String authToken = request.getHeader(jwtProperties.getHeader());
        if (StringUtils.isEmpty(authToken)) {
            //如果header中没有token，则检查请求参数中是否带token
            authToken = request.getParameter("token");
            if (StringUtils.isEmpty(authToken)) {
                log.error("获取登录token为空");
                throw new RuntimeException();
            }
        }

        //验证token是否正确
        Boolean flag = jwtTokenUtil.checkToken(authToken);
        if (flag) {
            log.info("access token ok");
            return null;
        } else {
            log.error("验证token失败，token不正确");
            throw new RuntimeException();
        }
    }

}
